// Copyright (c) 2020-present, INSPUR Co, Ltd. All rights reserved.
// This source code is licensed under Apache 2.0 License.
//
// Created by florian on 05.08.15.

#include <algorithm>
#include <assert.h>
#include "tree_node.h"

namespace syn_art_fullkey {

// void N256::deleteChildren() {
//   for (uint64_t i = 0; i < 256; ++i) {
//     if (children_[i] != nullptr) {
//       N::deleteChildren(children[i]);
//       N::deleteNode(children[i]);
//     }
//   }
// }

bool N256::insert(uint8_t key, N *val) {
  children_[key].store(val, std::memory_order_release);
  count_++;
  return true;
}

void N256::change(uint8_t key, N *n) {
  return children_[key].store(n, std::memory_order_release);
}

N *N256::getChild(const uint8_t k) const { return children_[k].load(); }

void N256::getChildrenSmall(uint8_t start, uint8_t end,
                       std::tuple<uint8_t, N *> *&children256,
                       uint32_t &childrenCount, u_int32_t childMax) const {
  childrenCount = 0;
  for (unsigned i = start; i <= end; i++) {
    N *child = this->children_[i].load();
    if (child != nullptr) {
      children256[childrenCount] = std::make_tuple(i, child);
      childrenCount++;
      if (childrenCount >= childMax)
          return;
    }
  }
}

void N256::getChildrenLarge(uint8_t start, uint8_t end,
                       std::tuple<uint8_t, N *> *&children256,
                       uint32_t &childrenCount, u_int32_t childMax) const {
  childrenCount = 0;
  for (unsigned i = end; i <= start; --i) {
    N *child = this->children_[i].load();
    if (child != nullptr) {
      children256[childMax - childrenCount - 1] = std::make_tuple(i, child);
      childrenCount++;
      if (childrenCount >= childMax)
        return;
    }
  }
  if (childrenCount > 0 && childrenCount < childMax) {
    memcpy(&(children256[0]), &(children256[childMax - childrenCount]),
           sizeof(std::tuple<uint8_t, N *>) * childrenCount);
  }
}

}  // namespace art_rowex